﻿using System.Reflection;
using System.Reflection.Metadata;
using System.Text;

namespace 反射
{
    internal class Program
    {
        static void Main(string[] args)
        {

            Person person = new Person();

            String name = person.GetTableFieldName("Id");
            Console.WriteLine(name);

            Console.WriteLine(person.CreateSelectSql());
            Console.WriteLine(person.CreateInsertSql());

            Console.WriteLine("Hello, World!");
        }

    }

    [TableModel(Name ="person")]
    internal class Person: BaseModel
    {
        [TableField(Name ="id")]
        public long Id { get; set; }

        [TableField(Name = "name")]
        public string Name { get; set; }

        [TableField(Name = "age")]
        public int Age {  get; set; }
        [TableField(Name = "sex")]
        public string Sex { get; set; }
        [TableField(Name = "addr")]
        public string Addr { get; set; }
    }

    [AttributeUsage(AttributeTargets.Property , AllowMultiple = true)]
    internal class TableField:Attribute
    {
        public string Name { get; set; }
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    internal class TableModel:Attribute 
    { 
    
        public string Name { get; set; }
    }

    internal class BaseModel
    {
        internal string GetTableFieldName(string pname)
        {
            String name = pname;
            // 获取Person类型的Type对象  
            Type type = this.GetType();


            // 获取MyProperty属性的PropertyInfo对象  
            PropertyInfo propertyInfo = type.GetProperty(pname);

            // 获取MyProperty属性上的特性（MyCustomAttribute）  
            object[] attributes = propertyInfo.GetCustomAttributes(false);
            foreach (var attribute in attributes)
            {
                if (attribute is TableField myAttribute)
                {
                    name = myAttribute.Name;     
                        
                }
            }
            return name;
        }

        internal string GetTableModelName()
        {
            
            Type type = this.GetType();

            String name = type.Name;

            object[] attributes = type.GetCustomAttributes(typeof(TableModel), false);
            foreach (var attribute in attributes)
            {
                if (attribute is TableModel myAttribute)
                {
                    name = myAttribute.Name; // 输出“这是一个类的描述”  
                }
            }
            return name;
        }


        internal string CreateSelectSql()
        {
            StringBuilder sb = new StringBuilder("select ");

            Type type = this.GetType();
            PropertyInfo[] propertyInfos = type.GetProperties();

            for (int i = 0;i<propertyInfos.Length;i++)
            {
                if(i == propertyInfos.Length - 1)
                {
                    sb.Append(GetTableFieldName(propertyInfos[i].Name));
                }
                else
                {
                    sb.Append(GetTableFieldName(propertyInfos[i].Name)).Append(", ");
                }
            }
            sb.Append(" from ").Append(GetTableModelName());
            return sb.ToString(); 
        }

        internal string CreateInsertSql()
        {

            StringBuilder sb = new StringBuilder("insert into ").Append(GetTableModelName());

            Type type = this.GetType();
            PropertyInfo[] propertyInfos = type.GetProperties();

            StringBuilder sb1 = new StringBuilder();
            StringBuilder sb2 = new StringBuilder();
            for (int i = 0; i < propertyInfos.Length; i++)
            {
                if (i == propertyInfos.Length - 1)
                {
                    sb1.Append(GetTableFieldName(propertyInfos[i].Name));
                    sb2.Append("@").Append(GetTableFieldName(propertyInfos[i].Name));
                }
                else
                {
                    sb1.Append(GetTableFieldName(propertyInfos[i].Name)).Append(", ");
                    sb2.Append("@").Append(GetTableFieldName(propertyInfos[i].Name)).Append(", ");
                }
            }

            sb.Append(" ( ").Append(sb1).Append(" ) ");
            sb.Append(" values ").Append(" ( ").Append(sb2).Append(" )");
            return sb.ToString();
        }

    }


}
